from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import create_engine
import bottle
import bottle_session
import bottle_redis
import redis
from jinja2 import environment

app = bottle.app()


###############################################################################
# sql setting #################################################################
###############################################################################
class DbManager:
    def __init__(self):
        self.pool_recycle = 3600
        self.databases = {'ENGINE': 'mysqlconnector', 'USER': 'root', 'PASSWORD': 'root', 'NAME': 'paytools', 'HOST': '127.0.0.1'}
        self.db_config = f'mysql+{self.databases["ENGINE"]}://{self.databases["USER"]}:{self.databases["PASSWORD"]}@{self.databases["HOST"]}/{self.databases["NAME"]}?charset=utf8mb4&autocommit=true'
        self.engine = create_engine(self.db_config, pool_size=100, pool_recycle=self.pool_recycle, pool_timeout=5)
        self.Session = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)

    def create_session(self, status):
        db = self.Session()
        if status == 0:
            return db
        else:
            db.rollback()
            db.expire_all()
            self.engine.dispose()
            Session = sessionmaker(autocommit=False, autoflush=False, bind=self.engine)
            db = Session()
            return db

    def __enter__(self):
        print("connect access link...")
        # return self.create_session(status=0)
        try:
            return self.create_session(status=0)
        except:
            return self.create_session(status=1)

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("close access link...")
        db = self.Session()
        db.close()


def session():
    with DbManager() as manager:
        return manager


def create_engin():
    engin = DbManager().engine
    return engin


Base = declarative_base()
db = session()

# 设置session回话管理模块（此处可以不用开启，如果你考虑使用cookies）
'''
in your apps for example:

If you want to use this model, you can follow these steps in view.py， or you can not allow this model.

@route('/')
def test(session, rdb):
    rdb.incr('visitors')
    visitor_num = rdb.get('visitors')
    # when cookie_lifetime=10, last_visit_time will be None
    last_visit_time = session['visit']
    session['visit'] = datetime.now().isoformat()
    # first time when you login this website, you can setting a dict like follwing
    session['name'] = '我爱你'
    name = session.get('name')
    return '<p>{},{},{}</p>'.format(visitor_num, last_visit_time, name)
'''


# session_plugin = bottle_session.SessionPlugin(cookie_lifetime=10)
# redis_plugin = bottle_redis.RedisPlugin()
# connection_pool = redis.ConnectionPool(host='127.0.0.1', port=6379)
# session_plugin.connection_pool = connection_pool
# redis_plugin.redisdb = connection_pool
# app.install(session_plugin)
# app.install(redis_plugin)